package io.plus.user_interface.server;

import io.plus.interactive.AioDecodeException;
import io.plus.interactive.AsynchronousSocketChannelContext;
import io.plus.interactive.Configuration;
import io.plus.interactive.user_interface.Packet;
import io.plus.server.ServerAioHandler;
import io.plus.user_interface.common.Status;
import io.plus.user_interface.common.UserConfiguration;
import io.plus.user_interface.common.io;
import io.plus.user_interface.common.packet.Command;
import io.plus.user_interface.common.packet.ResponseMessage;
import io.plus.user_interface.common.protocol.Decoder;
import io.plus.user_interface.common.protocol.Encoder;
import io.plus.user_interface.common.protocol.PacketImpl;
import io.plus.user_interface.server.command.AbstractCommandHandler;
import io.plus.user_interface.server.command.CommandManager;
import lombok.Data;

import java.nio.ByteBuffer;

@Data
public class ServerAioHandlerImpl implements ServerAioHandler {

    private UserConfiguration userConfiguration;

    public ServerAioHandlerImpl(UserConfiguration userConfiguration) {
        this.userConfiguration = userConfiguration;
    }

    @Override
    public Packet decode(AsynchronousSocketChannelContext asynchronousSocketChannelContext, ByteBuffer byteBuffer, int limit, int position, int readableLength) throws AioDecodeException {

        Packet tcpPacket = Decoder.decode(byteBuffer, asynchronousSocketChannelContext);
        return tcpPacket;
    }

    @Override
    public ByteBuffer encode(Configuration configuration, AsynchronousSocketChannelContext asynchronousSocketChannelContext, Packet packet) {
        PacketImpl tcpPacket = (PacketImpl) packet;
        return Encoder.encode(tcpPacket, configuration, asynchronousSocketChannelContext);
    }


    @Override
    public void handler(AsynchronousSocketChannelContext asynchronousSocketChannelContext, Packet packet) throws Exception {

        PacketImpl tcpPacket = (PacketImpl) packet;
        AbstractCommandHandler commandHandler = CommandManager.getCommandHandler(tcpPacket.getCommand());
        if (commandHandler == null) {
            PacketImpl packet1 = new PacketImpl(Command.unknow, new ResponseMessage(Command.unknow, Status.C10017).toByte());
            io.send(asynchronousSocketChannelContext, packet1);
            return;
        }
        PacketImpl response = commandHandler.handler(tcpPacket, asynchronousSocketChannelContext);
        if (response != null && tcpPacket.getSynchronismSerialNumber() < 1) {
            io.send(asynchronousSocketChannelContext, response);
        }
    }


}
